home *** CD-ROM | disk | FTP | other *** search
/ Suzy B Software 2 / Suzy B Software CD-ROM 2 (1994).iso / new_file / mintprgs / mint112s / mint112s.lzh / dossig.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-30  |  7.1 KB  |  329 lines

  1. /*
  2. Copyright 1990,1991,1992,1994 Eric R. Smith.
  3. All rights reserved.
  4. */
  5.  
  6. /* dossig.c:: dos signal handling routines */
  7.  
  8. #include "mint.h"
  9.  
  10. void ARGS_ON_STACK sig_user P_((int vec));
  11.  
  12. /*
  13.  * send a signal to another process. If pid > 0, send the signal just to
  14.  * that process. If pid < 0, send the signal to all processes whose process
  15.  * group is -pid. If pid == 0, send the signal to all processes with the
  16.  * same process group id.
  17.  *
  18.  * note: post_sig just posts the signal to the process.
  19.  */
  20.  
  21. long ARGS_ON_STACK
  22. p_kill(pid, sig)
  23.     int pid, sig;
  24. {
  25.     PROC *p;
  26.     long r;
  27.  
  28.     TRACE(("Pkill(%d, %d)", pid, sig));
  29.     if (sig < 0 || sig >= NSIG) {
  30.         DEBUG(("Pkill: signal out of range"));
  31.         return ERANGE;
  32.     }
  33.  
  34.     if (pid < 0)
  35.         r = killgroup(-pid, sig, 0);
  36.     else if (pid == 0)
  37.         r = killgroup(curproc->pgrp, sig, 0);
  38.     else {
  39.         p = pid2proc(pid);
  40.         if (p == 0 || p->wait_q == ZOMBIE_Q || p->wait_q == TSR_Q) {
  41.             DEBUG(("Pkill: pid %d not found", pid));
  42.             return EFILNF;
  43.         }
  44.         if (curproc->euid && curproc->ruid != p->ruid) {
  45.             DEBUG(("Pkill: wrong user"));
  46.             return EACCDN;
  47.         }
  48.  
  49. /* if the user sends signal 0, don't deliver it -- for users, signal
  50.  * 0 is a null signal used to test the existence of a process
  51.  */
  52.         if (sig != 0)
  53.             post_sig(p, sig);
  54.         r = 0;
  55.     }
  56.  
  57.     if (r == 0) {
  58.         check_sigs();
  59.         TRACE(("Pkill: returning OK"));
  60.     }
  61.     return r;
  62. }
  63.  
  64. /*
  65.  * set a user-specified signal handler, POSIX.1 style
  66.  * "oact", if non-null, gets the old signal handling
  67.  * behaviour; "act", if non-null, specifies new
  68.  * behaviour
  69.  */
  70.  
  71. long ARGS_ON_STACK
  72. p_sigaction(sig, act, oact)
  73.     int sig;
  74.     const struct sigaction *act;
  75.     struct sigaction *oact;
  76. {
  77.     TRACE(("Psigaction(%d)", sig));
  78.     if (sig < 1 || sig >= NSIG)
  79.         return ERANGE;
  80.     if (act && (sig == SIGKILL || sig == SIGSTOP))
  81.         return EACCDN;
  82.     if (oact) {
  83.         oact->sa_handler = curproc->sighandle[sig];
  84.         oact->sa_mask = curproc->sigextra[sig];
  85.         oact->sa_flags = curproc->sigflags[sig] & SAUSER;
  86.     }
  87.     if (act) {
  88.         ushort flags;
  89.  
  90.         curproc->sighandle[sig] = act->sa_handler;
  91.         curproc->sigextra[sig] = act->sa_mask & ~UNMASKABLE;
  92.  
  93. /* only the flags in SAUSER can be changed by the user */
  94.         flags = curproc->sigflags[sig] & ~SAUSER;
  95.         flags |= act->sa_flags & SAUSER;
  96.         curproc->sigflags[sig] = flags;
  97.  
  98. /* various special things that should happen */
  99.         if (act->sa_handler == SIG_IGN) {
  100.             /* discard pending signals */
  101.             curproc->sigpending &= ~(1L<<sig);
  102.         }
  103.  
  104. /* I dunno if this is right, but bash seems to expect it */
  105.          curproc->sigmask &= ~(1L<<sig);
  106.     }
  107.     return 0;
  108. }
  109.  
  110. /*
  111.  * set a user-specified signal handler
  112.  */
  113.  
  114. long ARGS_ON_STACK
  115. p_signal(sig, handler)
  116.     int sig;
  117.     long handler;
  118. {
  119.     long oldhandle;
  120.  
  121.     TRACE(("Psignal(%d, %lx)", sig, handler));
  122.     if (sig < 1 || sig >= NSIG)
  123.         return ERANGE;
  124.     if (sig == SIGKILL || sig == SIGSTOP)
  125.         return EACCDN;
  126.     oldhandle = curproc->sighandle[sig];
  127.     curproc->sighandle[sig] = handler;
  128.     curproc->sigextra[sig] = 0;
  129.     curproc->sigflags[sig] = 0;
  130.  
  131. /* various special things that should happen */
  132.     if (handler == SIG_IGN) {
  133.         /* discard pending signals */
  134.         curproc->sigpending &= ~(1L<<sig);
  135.     }
  136.  
  137. /* I dunno if this is right, but bash seems to expect it */
  138.     curproc->sigmask &= ~(1L<<sig);
  139.  
  140.     return oldhandle;
  141. }
  142.  
  143. /*
  144.  * block some signals. Returns the old signal mask.
  145.  */
  146.  
  147. long ARGS_ON_STACK
  148. p_sigblock(mask)
  149.     ulong mask;
  150. {
  151.     ulong oldmask;
  152.  
  153.     TRACE(("Psigblock(%lx)",mask));
  154. /* some signals (e.g. SIGKILL) can't be masked */
  155.     mask &= ~(UNMASKABLE);
  156.     oldmask = curproc->sigmask;
  157.     curproc->sigmask |= mask;
  158.     return oldmask;
  159. }
  160.  
  161. /*
  162.  * set the signals that we're blocking. Some signals (e.g. SIGKILL)
  163.  * can't be masked.
  164.  * Returns the old mask.
  165.  */
  166.  
  167. long ARGS_ON_STACK
  168. p_sigsetmask(mask)
  169.     ulong mask;
  170. {
  171.     ulong oldmask;
  172.  
  173.     TRACE(("Psigsetmask(%lx)",mask));
  174.     oldmask = curproc->sigmask;
  175.     curproc->sigmask = mask & ~(UNMASKABLE);
  176.     check_sigs();    /* maybe we unmasked something */
  177.     return oldmask;
  178. }
  179.  
  180. /*
  181.  * p_sigpending: return which signals are pending delivery
  182.  */
  183.  
  184. long ARGS_ON_STACK
  185. p_sigpending()
  186. {
  187.     TRACE(("Psigpending()"));
  188.     check_sigs();    /* clear out any that are going to be delivered soon */
  189.  
  190. /* note that signal #0 is used internally, so we don't tell the process
  191.  * about it
  192.  */
  193.     return curproc->sigpending & ~1L;
  194. }
  195.  
  196. /*
  197.  * p_sigpause: atomically set the signals that we're blocking, then pause.
  198.  * Some signals (e.g. SIGKILL) can't be masked.
  199.  */
  200.  
  201. long ARGS_ON_STACK
  202. p_sigpause(mask)
  203.     ulong mask;
  204. {
  205.     ulong oldmask;
  206.  
  207.     TRACE(("Psigpause(%lx)", mask));
  208.     oldmask = curproc->sigmask;
  209.     curproc->sigmask = mask & ~(UNMASKABLE);
  210.     if (curproc->sigpending & ~(curproc->sigmask))
  211.         check_sigs();    /* a signal is immediately pending */
  212.     else
  213.         sleep(IO_Q, -1L);
  214.     curproc->sigmask = oldmask;
  215.     check_sigs();    /* maybe we unmasked something */
  216.     TRACE(("Psigpause: returning OK"));
  217.     return 0;
  218. }
  219.  
  220. /*
  221.  * p_sigintr: Set an exception vector to send us the specified signal.
  222.  */
  223.  
  224. typedef struct usig {
  225.     int vec;        /* exception vector number */
  226.     int sig;        /* signal to send */
  227.     PROC *proc;        /* process to get signal */
  228.     long oldv;        /* old exception vector value */
  229.     struct usig *next;    /* next entry ... */
  230. } usig;
  231.  
  232. static usig *usiglst;
  233. extern long mcpu;
  234.  
  235. long ARGS_ON_STACK
  236. p_sigintr(vec, sig)
  237.     int vec;
  238.     int sig;
  239. {
  240.     extern void new_intr();    /* in intr.spp */
  241.     long vec2;
  242.     usig *new;
  243.  
  244.     if (!sig)        /* ignore signal 0 */
  245.         return 0;
  246.  
  247.     vec2 = (long) new_intr;
  248.  
  249. #ifndef ONLY030
  250.     if (mcpu == 0)            
  251.         /* put vector number in high byte of vector address */
  252.         vec2 |= ((long) vec) << 24;
  253. #endif
  254.     new = kmalloc(sizeof(usig));
  255.     if (!new)            /* hope this never happens...! */
  256.         return ENSMEM;
  257.     new->vec = vec;
  258.     new->sig = sig;
  259.     new->proc = curproc;
  260.     new->next = usiglst;        /* simple unsorted list... */
  261.     usiglst = new;
  262.  
  263.     new->oldv = setexc(vec, vec2);
  264.     return new->oldv;
  265. }
  266.  
  267. /*
  268.  * Find the process that requested this interrupt, and send it a signal.
  269.  * Called at interrupt time by new_intr() from intr.spp, with interrupt
  270.  * vector number on the stack.
  271.  */
  272.  
  273. void ARGS_ON_STACK
  274. sig_user(vec)
  275.     int vec;
  276. {
  277.     usig *ptr;
  278.  
  279.     for (ptr = usiglst; ptr; ptr=ptr->next)
  280.         if (vec == ptr->vec) {
  281.             if (ptr->proc->wait_q != ZOMBIE_Q &&
  282.                 ptr->proc->wait_q != TSR_Q) {
  283.                 post_sig(ptr->proc, ptr->sig);
  284.             }
  285. #if 0    /* Search entire list, to allow multiple processes to respond to
  286.        the same interrupt. (Why/when would you want that?) */
  287.             break;
  288. #endif
  289.         }
  290.     /*
  291.      * Clear in-service bit for ST MFP interrupts
  292.      */
  293.     if (vec >= 64 && vec < 80) {
  294.         char *mfp, c;
  295.  
  296.         if (vec < 72)        /* Register B */
  297.             mfp = (char *)0xfffffa11L;
  298.         else            /* Register A */
  299.             mfp = (char *)0xfffffa0fL;
  300.         c = 1 << (vec & 7);
  301.  
  302.         *mfp = ~c;
  303.     }
  304. }
  305.  
  306. /*
  307.  * cancelsigintrs: remove any interrupts requested by this process, called
  308.  * at process termination.
  309.  */
  310. void
  311. cancelsigintrs()
  312. {
  313.     usig *ptr, **old, *nxt;
  314.     short s = spl7();
  315.  
  316.     for (old=&usiglst, ptr=usiglst; ptr; ) {
  317.         nxt = ptr->next;
  318.         if (ptr->proc == curproc) {
  319.             setexc(ptr->vec, ptr->oldv);
  320.             *old = nxt;
  321.             kfree(ptr);
  322.         } else {
  323.             old = &(ptr->next);
  324.         }
  325.         ptr = nxt;
  326.     }
  327.     spl(s);
  328. }
  329.